import os
import sys
from imp import find_module
from imp import load_module

class PluginManager(type):
    __PluginPath = 'Plugins'
    __Tools = {}

    def __init__(self,name,bases,dict):
        if not hasattr(self,'AllPlugins'):
            self.__AllPlugins = {}
        else:
            self.RegisterAllPlugin(self)

    @staticmethod
    def SetTools(name, tool):
        PluginManager.__Tools[name] = tool

    @staticmethod
    def SetPluginPath(path):
        if os.path.isdir(path):
            PluginManager.__PluginPath = path
        else:
            print '%s is not a valid path' % path

    @staticmethod
    def LoadAllPlugin():
        pluginPath = PluginManager.__PluginPath
        if not os.path.isdir(pluginPath):
            raise EnvironmentError,'%s is not a directory' % pluginPath

        items = os.listdir(pluginPath)
        for item in items:
            if os.path.isdir(os.path.join(pluginPath,item)):
                PluginManager.__PluginPath = os.path.join(pluginPath,item)
                PluginManager.LoadAllPlugin()
            else:
                if item.endswith('.py') and item != '__init__.py':
                    moduleName = item[:-3]
                    if moduleName not in sys.modules:
                        fileHandle, filePath,dect = find_module(moduleName,[pluginPath])
                        try:
                            moduleObj = load_module(moduleName,fileHandle,filePath,dect)
                        finally:
                            if fileHandle : fileHandle.close()

    @property
    def AllPlugins(self):
        return self.__AllPlugins

    def RegisterAllPlugin(self,aPlugin):
        #print "register plugin", aPlugin
        pluginName = '.'.join([aPlugin.__module__,aPlugin.__name__])
        pluginObj = aPlugin()
        pluginObj.tools = self.__Tools
        self.__AllPlugins[pluginName] = pluginObj

    def UnregisterPlugin(self,pLuginName):
        if pluginName in self.__AllPlugins:
            pluginObj = self.__AllPlugins[pluginName]
            del pluginObj

    def GetPluginObject(self, pluginName = None):
        #print "get plugin", pluginName, self.__AllPlugins
        if pluginName is None:
            result = self.__AllPlugins.values()
            for plugin in result:
                plugin.prepare()
            return result
        else:
            result = self.__AllPlugins[pluginName] if pluginName in self.__AllPlugins else None
            if result:
                result.prepare()
            return result
